<template>
	<view class="rpc">
		<HeaderBar :title="chain?.chainName+'节点列表'" showBack backgroundColor="#F6F6F6" fixed>
			<template #right>
				<!-- <view class="more">更多</view> -->
			</template>
		</HeaderBar>
		<view class="content">
			<view class="cellTop">
				<view class="cellBox">
					<view class="state">
						<text>节点速度</text>
						<view class="block"></view>
						<text>快</text>
						<view class="block"></view>
						<text>中</text>
						<view class="block"></view>
						<text>慢</text>
					</view>
					<view class="con">
						区块高度: 高度值越大，代表节点数据同步更完善，其稳定性更好。 在节点速度差不多的情况下，选择高度值大的节点，体验更好
					</view>
				</view>

			</view>
			<view class="title">
				推荐节点
			</view>
			<view class="rpvList" :dataInfo="dataInfo" :change:dataInfo="renderjs.getdataInfo">
				<view class="rpvItem" v-for="(i,index) in rpcList" :key="index" @tap="setRpc(i)">
					<view class="name">
						{{i.url}}
						<image src="../../static/images/home/active1.png" mode="" class="icon" v-if="rpc&&i.url==rpc">
						</image>
					</view>
					<view class="info" v-if="i.ping">
						<view class="delay">
							{{i.ping}}ms
							<view :class="['block', getStateColor(i.ping)]"></view>
						</view>
						<view class="blockHeight">
							区块高度 {{i.blockHeight}}
						</view>
					</view>
					<view class="stutes" v-else>
						<image src="../../static/images/home/rpc.png" mode="" class="icon"></image>
					</view>
				</view>
			</view>
		</view>
		<!-- <view class="btn_box">
			<p>添加自定义节点</p>
		</view> -->
	</view>
</template>

<script>
	export default {
		data() {
			return {
				rpcList: [] // 用于存储节点信息，包括 ping 和区块高度
			}
		},
		computed: {
			chain() {
				return this.$store.getters.chainInfo
			},
			allChains() {
				return this.$store.getters.getAllchains
			},
			rpc() {
				return this.$store.getters.getRpc
			},
			dataInfo() {
				return {
					rpcList: this.chain?.rpc.map((url) => ({
						url: url,
						ping: null,
						blockHeight: null
					})),
					chainType: this.chain?.chainType,
				}
			}
		},
		mounted() {
			this.fetchNodeData()
		},
		methods: {
			setRpc(i) {
				this.$store.commit('setRpc', i.url);
			},
			getRpcState(list) {
				this.rpcList = list
			},
			async fetchNodeData() {
				this.rpcList = this.chain.rpc.map((url) => ({
					url: url,
					ping: null,
					blockHeight: null
				}));
			},
			getStateColor(ping) {
				if (ping === '请求失败') {
					return 'state3'; // 红色
				} else if (ping < 300) {
					return 'state1'; // 绿色
				} else if (ping <= 500) {
					return 'state2'; // 黄色
				} else {
					return 'state3'; // 红色
				}
			}
		}
	}
</script>
<script module="renderjs" lang="renderjs">
	export default {
		data() {
			return {
				jsLoadState: false,
				tjsLoadState: false,
				dataLoadState: false,
				dataInfo: {},
			}
		},
		mounted() {
			const ethersScript = document.createElement('script');
			ethersScript.src = 'static/script/ethers-5.2.umd.min.js';
			ethersScript.onload = async () => {
				this.jsLoadState = true;
				if (this.dataLoadState) {
					this.getBlockHeight()
				}
			};
			document.head.appendChild(ethersScript);
			// 载入 TronWeb.js
			const tronWebScript = document.createElement('script');
			tronWebScript.src = 'static/script/newTronWeb.js';
			tronWebScript.onload = () => {
				this.tjsLoadState = true;
				if (this.dataLoadState) {
					this.getBlockHeight()
				}
			};
			document.head.appendChild(tronWebScript);
		},
		methods: {
			//同步数据
			async getdataInfo(newValue) {
				if (JSON.stringify(this.dataInfo) === JSON.stringify(newValue)) return;
				this.dataInfo = newValue
				this.dataLoadState = true
				this.getBlockHeight()
			},
			async getBlockHeight() {
				if (this.dataInfo?.chainType == 'ETH' && this.jsLoadState) {
					const promises = this.dataInfo.rpcList.map(async (i) => {
						let provider = new ethers.providers.JsonRpcProvider(i.url);
						try {
							const start = Date.now();
							let blockHeight = await Promise.race([
								provider.getBlockNumber(),
								new Promise((_, reject) => setTimeout(() => reject(new Error(
									'Request timed out')), 3000)) // 5秒超时
							]);
							const ping = Date.now() - start;
							i.blockHeight = blockHeight;
							i.ping = ping;
						} catch (e) {
							i.blockHeight = null;
							i.ping = null;
						}
					});
					await Promise.all(promises);
					this.$ownerInstance.callMethod('getRpcState', this.dataInfo.rpcList);

				} else if (this.dataInfo?.chainType == 'TRON' && this.tjsLoadState) {

					const promises = this.dataInfo.rpcList.map(async (i) => {
						const tronWeb = new TronWeb.TronWeb({
							fullHost: i.url,
						});
						try {
							const start = Date.now();
							let block = await Promise.race([
								tronWeb.trx.getCurrentBlock(),
								new Promise((_, reject) => setTimeout(() => reject(new Error(
									'Request timed out')), 3000)) // 5秒超时
							]);
							if (block && block.block_header && block.block_header.raw_data) {
								let blockHeight = block.block_header.raw_data.number;
								const ping = Date.now() - start;
								i.blockHeight = blockHeight;
								i.ping = ping;
							} else {
								throw new Error('Invalid block response');
							}
						} catch (e) {
							i.blockHeight = null;
							i.ping = null;
						}
					});
					await Promise.all(promises);
					this.$ownerInstance.callMethod('getRpcState', this.dataInfo.rpcList);

				}
			}
		},
	}
</script>
<style lang="scss" scoped>
	.rpc {
		min-height: 100%;
		background: #F6F6F6;
		font-weight: 400;

		.more {
			font-size: 30upx;
		}

		.content {
			padding-bottom: 140upx;

			.cellTop {
				padding: 40upx 44upx;

				.cellBox {
					background: #FFF;
					border-radius: 20upx;
					color: #979797;
					padding: 10upx 20upx;

					.state {
						display: flex;
						align-items: center;
						font-size: 22upx;

						.block {
							width: 18upx;
							height: 18upx;
							border-radius: 9upx;
							margin-left: 20upx;
							margin-right: 10upx;

							&:nth-of-type(1) {
								background: #368321;
							}

							&:nth-of-type(2) {
								background: #F9B909;
							}

							&:nth-of-type(3) {
								background: #D73C3C;
							}
						}
					}

					.con {
						font-size: 22upx;
					}
				}

			}

			.title {
				color: #979797;
				font-size: 24upx;
				padding: 0 20upx;
				margin-bottom: 10upx;
			}

			.rpvList {
				background: #FFF;

				.rpvItem {
					display: flex;
					justify-content: space-between;
					padding: 0 20upx;
					height: 94upx;
					align-items: center;

					.name {
						font-size: 20upx;
						display: flex;
						align-items: center;

						.icon {
							width: 32upx;
							height: 32upx;
							margin-left: 20upx;
						}

					}

					.stutes {
						display: flex;

						.icon {
							width: 20upx;
							height: 15upx;
						}
					}

					.info {
						text-align: right;

						.delay {
							display: flex;
							align-items: center;
							font-size: 22upx;
							justify-content: flex-end;

							.block {
								width: 12upx;
								height: 12upx;
								border-radius: 6upx;
								margin-left: 10upx;
							}

							.state1 {
								background: #368321;
							}

							.state2 {
								background: #F9B909;
							}

							.state3 {
								background: #D73C3C;
							}
						}

						.blockHeight {
							font-size: 20upx;
							color: #979797;
						}
					}
				}
			}
		}

		.btn_box {
			position: fixed;
			width: 100%;
			height: 100upx;
			background: #FFF;
			display: flex;
			align-items: center;
			justify-content: center;
			left: 0;
			bottom: 0;
			color: #368321;
			font-size: 28upx;
		}
	}
</style>